home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -websites- / wirenet / files / thor26_arexx.lha / Rexx / ShowHTML.thor < prev    next >
Text File  |  1999-01-17  |  12KB  |  468 lines

  1. /*
  2. ** $VER: ShowHTML.thor 1.3 (27.3.98)
  3. **
  4. ** by Eirik Nicolai Synnes <eirikns@ifi.uio.no>
  5. **
  6. ** ShowHTML.thor will send a HTML document in the message currently displayed
  7. ** in Thor's main window to a web browser.  First it searches for a browser
  8. ** already in memory and uses this one, uniconifying it if necessary.  If no
  9. ** browser is active it will launch the browser configured using CfgHTTP.thor.
  10. **
  11. ** Currenly ShowHTML.thor recognizes IBrowse, AWeb, Voyager and AMosaic.
  12. **
  13. **
  14. ** New in 1.3:
  15. **
  16. **   o Supports attachments (inline images) in messages posted with
  17. **     Netscape 4.0 and Microsoft Outlook Express (at least newer
  18. **     versions)
  19. **   o Improved screen-to-front and browser activation
  20. ** 
  21. **
  22. ** Fixed in 1.2:
  23. **
  24. **   o If ShowHTML wanted to display a requestor it would fail with
  25. **     an ARexx error
  26. **
  27. **
  28. ** New in 1.1:
  29. **
  30. **   o HTML search routines vastly improved
  31. **   o Added support for Voyager (2.88 tested, might not work with earlier
  32. **     versions)
  33. **   o Added support for AMosaic (not tested)
  34. **   o Now uses CfgHTTP.thor's configuration file to figure out how to start
  35. **     the browser
  36. **   o Browser window is always brought to front and activated (if the
  37. **     browser's ARexx port support it)
  38. **   o Lots of minor enhancements and bug fixes
  39. **
  40. **
  41. ** Todo:
  42. **
  43. **   o Delete shows "Delete returned 20" if it couldn't delete the temporary
  44. **     file. Is it possible to get rid of this?
  45. **
  46. **   o There's still some weird methods of attaching HTML documents
  47. **     which ShowHTML doesn't check for
  48. **
  49. **   o See if it is possible to wait for something in order to avoid
  50. **     temp file getting deleted before the browser has loaded it
  51. **
  52. */
  53.  
  54. options results
  55. options failat 31
  56.  
  57. signal on break_c
  58. signal on halt
  59. signal on error
  60.  
  61. globals = 'poster atts. htmlstem fileopen filename outfile THOR.LASTERROR BBSREAD.LASTERROR thorport msgtext. wwwcmd wwwport globals'
  62.  
  63. waitforport = 'SYS:RexxC/WaitForPort'
  64.  
  65. fileopen    = 0
  66. filename    = 'T:SaveHTML.' || pragma('ID') || '.html'
  67.  
  68. poster      = ''
  69. atts.count  = 0
  70.  
  71.  
  72. /*
  73. ** See if I'm run from Thor
  74. */
  75.  
  76. if (left(address(), 5) = 'THOR.') then thorport = address()
  77. else do
  78.     say 'This script must be run from Thor.'
  79.     exit(20)
  80.     end
  81.  
  82.  
  83. /*
  84. ** Find/open BBSREAD ARexx port
  85. */
  86.  
  87. if ~(show('P', 'BBSREAD')) then do
  88.     address(command)
  89.     'Run >NIL: `GetEnv THOR/THORPath`bin/LoadBBSRead'
  90.     'WaitForPort BBSREAD'
  91.     if (rc ~= 0) then displayerror(30, 'SortMail', 'Couldn''t open BBSREAD''s ARexx port.')
  92.     end
  93.  
  94. call loadprefs()
  95.  
  96. /*
  97. ** Read the current message
  98. */
  99.  
  100. address(thorport)
  101. 'CURRENTMSG STEM 'curmsg
  102. if (rc ~= 0) then call fail('Couldn''t detect a current message.')
  103.  
  104. address(bbsread)
  105. 'READBRMESSAGE "'curmsg.BBSNAME'" "'curmsg.CONFNAME'" 'curmsg.MSGNR' TEXTSTEM 'msgtext
  106. if (rc ~= 0) then call fail('Couldn''t read message:\n'BBSREAD.LASTERROR)
  107.  
  108. /*
  109. ** Find out what program posted/mailed the message
  110. */
  111.  
  112. if (symbol('msgtext.COMMENT.COUNT') = 'VAR') & (msgtext.COMMENT.COUNT > 0) then do i = 1 to msgtext.COMMENT.COUNT while poster = ''
  113.     if (upper(subword(msgtext.COMMENT.i, 2, 1)) = 'MOZILLA') then poster = 'mozilla'
  114.     if (upper(subword(msgtext.COMMENT.i, 2, 3)) = 'MICROSOFT OUTLOOK EXPRESS') then poster = 'outlook'
  115. end
  116.  
  117.  
  118. /*
  119. ** Find out what browser(s) is/are active
  120. */
  121.  
  122. call findbrowser()
  123.  
  124. /*
  125. ** Find a text/html part
  126. */
  127.  
  128. if ~(findhtml('msgtext', 0)) then do
  129.     if (symbol('msgtext.TEXT.COUNT') = 'VAR') & (msgtext.TEXT.COUNT > 0) then do
  130.         address(thorport)
  131.         'REQUESTNOTIFY TEXT "No text/html message part found.\nDo you want to send the first\nmessage part to the browser?" BT "Yes|No"'
  132.         if (rc ~= 0) then do
  133.             say 'Couldn''t open requester: 'THOR.LASTERROR
  134.             exit(0)
  135.         end
  136.         if (result = 1) then call savemsg('msgtext')
  137.         else exit(0)
  138.     end
  139.     else fail('No text/html message part found.')
  140. end
  141. else call savemsg(value('htmlstem'))
  142.  
  143.  
  144. /*
  145. ** Display HTML document
  146. */
  147.  
  148. if symbol('wwwport') ~= 'VAR' then do
  149.     address command 'Run <NIL: >NIL: 'wwwcmd' file://localhost/' || filename
  150.     if (rc ~= 0) then fail('Failed to run browser.')
  151. end
  152. else do
  153.     address(wwwport)
  154.     select
  155.         when wwwport = 'VOYAGER' then 'OPENURL file://localhost/' || filename
  156.         when wwwport = 'IBROWSE' then 'GOTOURL file://localhost/' || filename
  157.         when left(wwwport, 5) = 'AWEB.' then 'OPEN URL file://localhost/' || filename || ' RELOAD'
  158.         when left(wwwport, 8) = 'AMOSAIC.' then 'JUMP URL file://localhost/' || filename
  159.         otherwise nop
  160.     end
  161.     if (rc ~= 0) then call fail('Browser failed to display document.')
  162. end
  163.  
  164.  
  165. /*
  166. ** Activate browser window
  167. */
  168.  
  169. if (symbol('wwwport') ~= 'VAR') then call findbrowser
  170.  
  171. if (symbol('wwwport') = 'VAR') then do
  172.     if (exists(waitforport)) then do
  173.         do i = 1 to 6
  174.             address(command)
  175.             waitforport || ' ' || wwwport
  176.             if (rc = 0) then leave i
  177.         end
  178.     end
  179.     else say 'Hey, I could not find ' || waitforport || '. Please fix this!'
  180.  
  181.     if (rc ~= 0) then signal cleanup
  182. end
  183.  
  184. address(wwwport)
  185.  
  186. select
  187.     when (wwwport = 'VOYAGER') then do
  188.         'SHOW'
  189.         'ACTIVATE'
  190.     end
  191.     when (wwwport = 'IBROWSE') then do
  192.         'SHOW'
  193.         'SCREENTOFRONT'
  194.         'ACTIVATE'
  195.     end
  196.     when (left(wwwport, 5) = 'AWEB.') then do
  197.         'WINDOWTOFRONT'
  198.         'SCREENTOFRONT'
  199.         'ACTIVATEWINDOW'
  200.     end
  201.     when (left(wwwport, 8) = 'AMOSAIC.') then do
  202.         'SHOW'
  203.         'ACTIVATE'
  204.     end
  205.     otherwise nop
  206. end
  207.  
  208. /*
  209. ** Clean up and exit
  210. */
  211.  
  212. cleanup:
  213. break_c:
  214. halt:
  215. error:
  216.  
  217. if fileopen = 1 then call close(outfile)
  218.  
  219.  
  220. /*
  221. ** See if the file can be deleted. Checks every 10 seconds.
  222. */
  223.  
  224. if exists(filename) then do
  225.     options failat 31
  226.     address(command)
  227.     'Wait 10'
  228.     do i = 1 to 12
  229.         'Wait 10'
  230.         'Delete >NIL: QUIET "'filename'"'
  231.         if (rc = 0) then leave i
  232.     end
  233. end
  234.  
  235. exit(0)
  236.  
  237.  
  238. /****************************************************************************
  239. ********************************** Procedures ********************************
  240.  ***************************************************************************/
  241.  
  242.  
  243. /**
  244. *** Recursive function for finding text/html part and related message parts
  245. **/
  246.  
  247. findhtml: interpret 'procedure expose 'globals
  248.           parse arg tstem, saverel
  249.  
  250. foundct = 0; foundrel = 0; foundcid = 0
  251.  
  252. if (symbol(tstem'.COMMENT.COUNT') = 'VAR') & (value(tstem'.COMMENT.COUNT') > 0) then do i = 1 to value(tstem'.COMMENT.COUNT')
  253.     curline = value(tstem'.COMMENT.i')
  254.  
  255.     if (index(upper(curline), 'CONTENT-TYPE:') > 0) then do
  256.         content = substr(curline, index(upper(curline), 'CONTENT-TYPE:') + 13)
  257.         if (index(content, ';') > 0) then content = substr(content, 1, index(content, ';'))
  258.         content = compress(content, ' ;')
  259.  
  260.         if (upper(content) = 'TEXT/HTML') then foundct = 1
  261.         if (upper(content) = 'MULTIPART/RELATED') then foundrel = 1
  262.         drop content
  263.     end
  264.  
  265.     if (index(upper(curline), 'CONTENT-ID:') > 0) then do
  266.         id = substr(curline, index(upper(curline), 'CONTENT-ID:') + 13)
  267.         if (index(id, ';') > 0) then id = substr(id, 1, index(id, ';'))
  268.         id = compress(id, ' <>;'); foundcid = 1
  269.     end
  270. end
  271.  
  272. if (foundrel = 0) & (foundct = 0) then if (upper(value(tstem'.BINARY.DESC')) = 'TEXT/HTML' | upper(right(value(tstem'.BINARY'), 4)) = '.HTML' | upper(right(value(tstem'.BINARY'), 4)) = '.HTM') then foundct = 1
  273.  
  274. if (foundct) then do
  275.     htmlstem = tstem
  276.     if ~(saverel) then do
  277.         return(1)
  278.     end
  279. end
  280.  
  281. if (foundcid) & (saverel) then do
  282.     if (symbol(tstem'.PART.1.BINARY') = 'VAR') then do
  283.         att = value(tstem'.PART.1.BINARY')
  284.         if (exists(att)) then do
  285.             cnt = atts.count; cnt = cnt + 1
  286.             atts.cnt.cid  = id
  287.             atts.cnt.file = att
  288.             atts.count = cnt; drop cnt
  289.         end
  290.         return(1)
  291.     end
  292. end
  293.  
  294. if (symbol(tstem'.PART.COUNT') = 'VAR') & (value(tstem'.PART.COUNT') > 0) then do i = 1 to value(tstem'.PART.COUNT')
  295.     newstem = tstem || '.PART.' || i || '.MSG'
  296.  
  297.     if (foundrel) then call findhtml(newstem, 1)
  298.     else call findhtml(newstem, saverel)
  299.  
  300.     if (result = 1) then return(1)
  301. end
  302.  
  303. return(0)
  304.  
  305.  
  306.  
  307. /**
  308. *** SAVE A MESSAGEPART TO DISK
  309. **/
  310.  
  311. savemsg: interpret 'procedure expose 'globals
  312.             parse arg htmltext
  313.  
  314.  
  315. /*
  316. ** Write text body
  317. */
  318.  
  319. if (symbol(htmltext'.TEXT.COUNT') = 'VAR') then do
  320.     cnt = value(htmltext'.TEXT.COUNT')
  321.  
  322.     if (cnt > 0) then do
  323.         fileopen = open(outfile, filename, 'W')
  324.         if ~(fileopen) then do
  325.             call fail('Couldn''t open "' || filename || '" for writing.')
  326.             return(20)
  327.         end
  328.  
  329.         select
  330.             when (poster = 'mozilla') | (poster = 'outlook') then do
  331.                 do i = 1 to cnt
  332.                     line = value(htmltext'.TEXT.'i)
  333.                     if (index(line, 'cid:') > 0) then do
  334.                         do j = 1 to atts.count
  335.                             do while (index(line, 'cid:' || atts.j.cid) > 0)
  336.                                 line = substitute(line, 'cid:' || atts.j.cid, 'file://localhost/' || atts.j.file, 1)
  337.                             end
  338.                         end
  339.                         call writeln(outfile, line)
  340.                     end
  341.                     else call writeln(outfile, line)
  342.                 end
  343.             end
  344.             otherwise do i = 1 to cnt
  345.                 call writeln(outfile, value(htmltext'.TEXT.'i))
  346.             end
  347.         end
  348.  
  349.         call close(outfile)
  350.     end
  351.     else if (symbol(htmltext'.PART.1.BINARY') = 'VAR') & (value(htmltext'.PART.1.BINARY.DESC') = 'text/html') then do
  352.         htmlpath = value(htmltext'.PART.1.BINARY')
  353.         if ~(exists(htmlpath)) then fail('text/html part was deleted or not found.')
  354.         else address command 'Copy "'htmlpath'" TO "'filename'" QUIET'
  355.     end
  356.  
  357.     else fail('text/html part was empty.')
  358. end
  359. else fail('Incorrect html message stem')
  360.  
  361. return(0)
  362.  
  363.  
  364. /*
  365. ** Find an active browser, run one if none is found
  366. */
  367.  
  368. findbrowser: interpret 'procedure expose 'globals
  369.  
  370. /* Go through available ports */
  371.  
  372. ports = show('P')
  373.  
  374. do i = 1 to words(ports)
  375.     if left(subword(ports, i), 5) = 'AWEB.'    then wwwport = subword(ports, i, 1)
  376.     if left(subword(ports, i), 8) = 'AMOSAIC.' then wwwport = subword(ports, i, 1)
  377.     if left(subword(ports, i), 7) = 'VOYAGER'  then wwwport = subword(ports, i, 1)
  378.     if left(subword(ports, i), 7) = 'IBROWSE'  then wwwport = subword(ports, i, 1)
  379.     if symbol('wwwport') = 'VAR' then break
  380. end
  381.  
  382. if left(subword(ports, i), 5) = 'AWEB.' then do
  383.     address(wwwport)
  384.     'GET ACTIVEPORT'
  385.     if (rc = 0 ) then wwwport = result
  386. end
  387.  
  388. return(0)
  389.  
  390.  
  391. /*
  392. ** Display an error message and exit
  393. */
  394.  
  395. fail: interpret 'procedure expose 'globals
  396.       parse arg errtext
  397.  
  398. address(thorport)
  399.  
  400. 'REQUESTNOTIFY TEXT "'errtext'" BUTTONTEXT "Abort"'
  401. if (rc ~= 0) then do
  402.     say 'Couldn''t open error requester: 'THOR.LASTERROR
  403.     say 'Original error was: 'errtext
  404. end
  405.  
  406. signal cleanup
  407.  
  408.  
  409. /*
  410. ** Load preferences saved by CfgHTTP.thor
  411. */
  412.  
  413. loadprefs: interpret 'procedure expose 'globals
  414.  
  415. cfgfile = 'ENV:Thor/http.config'
  416.  
  417. if ~(exists(cfgfile)) then do
  418.     address(thorport)
  419.     'REQUESTNOTIFY TEXT "Could not find the configuration file.\nRun CfgHTTP to create one or quit." BT "CfgHTTP|Quit"'
  420.     if (rc = 0) & (result = 1) then address command 'rx `GetEnv THOR/THORPath`rexx/cfghttp.thor'
  421.     exit(0)
  422. end
  423. else do
  424.     call open(prf, cfgfile, 'R')
  425.     do until eof(prf)
  426.         line = readln(prf)
  427.         if upper(word(line, 1)) = 'BROWSEREXE' then wwwcmd = subword(line, 2)
  428.     end
  429.     call close(prf)
  430. end
  431.  
  432. return(0)
  433.  
  434.  
  435.  /****************************************************************************
  436. ********************* Substitute a string within a string *********************
  437. ******** Shamelessly ripped from Troels Walsted Hansen's UUDecode.thor ********
  438.  ****************************************************************************/
  439.  
  440. substitute: interpret 'procedure expose 'globals
  441.             parse arg str, org, new, quote
  442.  
  443. /*
  444. ** str   = original string
  445. ** org   = string to replace
  446. ** new   = string to replace with
  447. ** quote = add quotes around the string part replaced if there
  448. **         aren't any quotes already (useful for URL replacing)
  449. */
  450.  
  451. lastfound = 0; if (quote = '') then quote = 0
  452.  
  453. found = index(str, org)
  454.  
  455. do while found > lastfound
  456.     secondpart = substr(str, found + length(org))
  457.     firstpart = substr(str, 1, length(str) - length(substr(str, found)))
  458.     if (quote) then do 
  459.         if (right(firstpart, 1) ~= '"') then firstpart = firstpart || '"'
  460.         if (left(secondpart, 1) ~= '"')   then secondpart = '"' || secondpart
  461.     end
  462.     str = firstpart || new || secondpart
  463.     lastfound = found + length(new)
  464.     found = index(str, org, lastfound)
  465. end
  466.  
  467. return(str)
  468.